//LiteXLoader Dev Helper
/// <reference path="c:\Users\Yoyo\.vscode\extensions\moxicat.lxldevhelper-0.1.4/Library/JS/Api.js" /> 

/* 
插件名:快捷创建
作者:Yoyo
版本:v0.0.3
LXL支持版本: >= 0.5.6
介绍:没啥特殊用法,就是方便建造!反正就是更加方便罢了!
*/

const CONFIG = new JsonConfigFile(".\\plugins\\Yoyo\\create\\config.json", JSON.stringify({
    menu: {
        "填充区域": {
            explain: "这是填充一个区域哦!",
            pos: 2,
            ps: ["第一坐标已选择", "第二坐标已选择"],
            list: {
                "填充方块[输入id](插件填充,因为原版指令有限制)": {
                    type: "block",
                    fill: true
                },
                "填充方块[输入id]": {
                    type: "block",
                    cmd: "fill {pos[0]} {pos[1]} {block}"
                },
                "填充空气(插件填充,因为原版指令有限制)": {
                    fill: true,
                    block: "air"
                },
                "填充空气": {
                    cmd: "fill {pos[0]} {pos[1]} air"
                }
            }
        },
        "方块延申": {
            explain: "请点击需要延申的方块",
            pos: 1,
            ps: ["方块已选择"],
            list: {
                "开始延申该方块": {
                    type: "continue_area"
                }
            }
        },
        "复制区域并粘贴": {
            pos: 3,
            ps: ["第一坐标已选择", "第二坐标已选择", "粘贴的位置已确定"],
            list: {
                "仅粘贴非空气方块": {
                    cmd: "clone {pos[0]} {pos[1]} {pos[2]} masked"
                },
                "粘贴所有方块": {
                    cmd: "clone {pos[0]} {pos[1]} {pos[2]} replace"
                }
            }
        }
    }
}));

var onUseItemOnTime = {}, ItemName = "§l§g神奇的板砖", ItemType = "minecraft:brick", Cname = "CreateData";
/* 监听 */
mc.listen("onUseItemOn", onUseItemOn);
mc.listen("onJoin", CplData);
mc.listen("onServerStarted", onServerStarted);
/* 
0 = z+
1 = x-
2 = z-
3 = x+
*/
/* 命令 */
mc.regPlayerCmd("ctool", "§l§g获得快捷创造工具", getcTool, 1)

function onUseItemOn(player, item, block) {
    if (!player.isOP()) return true;
    if (item.name != ItemName) return true;
    if (item.type != ItemType) return true;
    let ItemNbt = item.getNbt();
    let Nbtdisplay = ItemNbt.getTag("tag").getTag("display");
    let displayLore = Nbtdisplay.getTag("Lore");
    if (typeof displayLore == "undefined") return true;
    let itemXuid = displayLore.getTag(4);
    if (typeof itemXuid == "undefined") return true;
    if (itemXuid.get() != player.xuid) {
        msg(player, "这个工具它不属于你!", 4);
        return true;
    }
    if (typeof onUseItemOnTime[player.xuid] != "undefined") clearInterval(onUseItemOnTime[player.xuid]);
    onUseItemOnTime[player.xuid] = setTimeout(() => {
        cmenu(player, item, block);
    }, 80);
    return false;
}

function cmenu(player, item, block) {
    let plData = player.getExtraData(Cname);
    let configs = CONFIG.get("menu");
    if (typeof plData == "undefined") {
        /* 不存在就重新初始化 */
        CplData(player);
    }
    if (plData.type != null) {
        /* 已选择类型开始选点 */
        let ctype = configs[plData.type];
        /* 记录选点 */
        plData.pos.data.push({ x: block.pos.x, y: block.pos.y, z: block.pos.z });
        player.setExtraData(Cname, plData);
        if (typeof ctype.ps[plData.pos.data.length - 1] == "undefined") {
            msg(player, `已选择第§5${plData.pos.data.length}§2个点`);
        } else {
            msg(player, ctype.ps[plData.pos.data.length - 1]);
        }
        /* 顺便判断是否已经选点完成 */
        if (plData.pos.data.length >= plData.pos.num) {
            /* 完成,弹出子级菜单 */
            SonMenu(player);
        }
    } else {
        /* 未选择类型,打开GUI菜单 */
        HomeMenu(player);
    }
}


function getcTool(player) {
    let NewItem = mc.newItem(ItemType, 1);
    let Nbt = NewItem.getNbt();
    Nbt.setTag("tag", new NbtCompound({
        "minecraft:item_lock": new NbtByte(0),
        "minecraft:keep_on_death": new NbtByte(1),
        "display": new NbtCompound({
            "Name": new NbtString(ItemName)
        }),
        "Unbreakable": new NbtByte(1)
    }));
    Nbt.setByte("Count", 1);
    NewItem.setNbt(Nbt);
    NewItem.setLore(["§l§4使用权(OP)", "§l§e持有物品点击方块设置坐标", "§l§5该物品输入指令/ctool获得", "§l§6物品创建者:" + player.name, player.xuid]);
    player.giveItem(NewItem);
    player.refreshItems();
    msg(player, "已赐予你建造工具!");
}

function msg(player, txt, type = 2) {
    player.tell(`§l§${type}[§e快捷创造§${type}]${txt}`);
}

function CplData(player) {
    player.setExtraData(Cname, {
        type: null, pos: {
            num: 0,
            data: [
                { x: 0, y: 0, z: 0 }
            ]
        }
    });
}

function HomeMenu(player) {
    let plData = player.getExtraData(Cname);
    let configs = CONFIG.get("menu");
    let TypeList = Object.keys(configs);
    let utw = mc.newSimpleForm();
    utw.setTitle("§l§e请选择操作类型");
    TypeList.forEach(a => utw.addButton(a));
    player.sendForm(utw, (player, id) => {
        if (id == null && id != 0) return false;
        plData.type = TypeList[id];
        plData.pos.num = configs[TypeList[id]].pos;
        plData.pos.data = [];
        if (typeof configs[TypeList[id]].explain != "undefined") {
            msg(player, configs[TypeList[id]].explain);
        }
        msg(player, "请开始操作!");
        player.setExtraData(Cname, plData);
    });
}

function SonMenu(player) {
    let plData = player.getExtraData(Cname);
    let configs = CONFIG.get("menu");
    let SonList = Object.keys(configs[plData.type].list);
    let utw = mc.newSimpleForm();
    utw.setTitle("§l§e已选择成功,请选择下一步操作");
    SonList.forEach(a => utw.addButton(a));
    player.sendForm(utw, (player, id) => {
        if (id == null && id != 0) return false;
        let SonData = configs[plData.type].list[SonList[id]];
        if (typeof SonData.type == "undefined") {
            if (typeof SonData.fill != "undefined") {
                /* 插件填充 */
                if (typeof SonData.block == "undefined") SonData.block = "air";
                msg(player, "正在处理中!", 3);
                yofill(plData.pos.data[0], plData.pos.data[1], SonData.block, player.pos.dimid);
                msg(player, "处理完成!", 2);
            } else {
                /* 直接执行 */
                let cmd = SonData.cmd;

                let seCount = cmd.match(/{pos\[\d+\]}/g);
                if (seCount == null) {
                    cmd = cmd.replace(/{pos\[\d+\]}/g, '');
                } else {

                    seCount.forEach((v, k) => {
                        if (plData.pos.data[k] instanceof Object) {
                            cmd = cmd.replace(v, postostr(plData.pos.data[k]));
                        } else {
                            cmd = cmd.replace(v, '');
                        }
                    });
                }
                player.runcmd(cmd);
            }
            CplData(player);
        } else if (SonData.type == "block") {
            /* 输入方块id */
            inputUtw(player, SonList[id]);
        } else if (SonData.type == "continue_area") {
            /* 延申方块 */
            continuegui(player, SonList[id]);
        } else {
            /* 错误 */
        }
    });
}

function continuegui(player, id) {
    let plData = player.getExtraData(Cname);
    let configs = CONFIG.get("menu");
    let utw = mc.newCustomForm();
    utw.setTitle("§l§e请输入需要延申的(§4格数§e)");
    utw.addInput("延申格数", "格数");
    utw.addSwitch("上", false);
    utw.addSwitch("下", false);
    utw.addSwitch("左", false);
    utw.addSwitch("右", false);
    utw.addSwitch("前", false);
    utw.addSwitch("后", false);
    player.sendForm(utw, (player, datas) => {
        if (datas == null) {
            CplData(player);
            msg(player, "已取消操作!!", 4);
            return false;
        }
        /* 直接执行 */
        let stats = plData.pos.data[0];
        let NewBl = mc.getBlock(stats.x, stats.y, stats.z, player.pos.dimid);
        for (let is = 1; is < datas.length; is++) {
            if (datas[is]) {
                continueBlock({ x: stats.x, y: stats.y, z: stats.z, dimid: player.pos.dimid }, is, Number(datas[0]), NewBl, player.direction.toFacing());
            }
        }
        CplData(player);
    });
}


function continueBlock(pos, direction, number, block, Facing) {
    let newpos = {x:pos.x,y:pos.y,z:pos.z};
    switch (`${direction}`) {
        case "1":
            newpos.y += number;
            break;
        case "2":
            newpos.y -= number;
            break;
        case "3":
            if (Facing == 0) newpos.x += number;
            if (Facing == 1) newpos.z += number;
            if (Facing == 2) newpos.x -= number;
            if (Facing == 3) newpos.z -= number;
            break;
        case "4":
            if (Facing == 0) newpos.x -= number;
            if (Facing == 1) newpos.z -= number;
            if (Facing == 2) newpos.x += number;
            if (Facing == 3) newpos.z += number;
            break;
        case "5":
            if (Facing == 0) newpos.z += number;
            if (Facing == 1) newpos.x -= number;
            if (Facing == 2) newpos.z -= number;
            if (Facing == 3) newpos.x += number;
            break;
        case "6":
            if (Facing == 0) newpos.z -= number;
            if (Facing == 1) newpos.x += number;
            if (Facing == 2) newpos.z += number;
            if (Facing == 3) newpos.x -= number;
            break;
    }
    yofill(pos,newpos, block, pos.dimid);
}

function inputUtw(player, id) {
    let plData = player.getExtraData(Cname);
    let plDataBlock = player.getExtraData(Cname + "_block");
    if (typeof plDataBlock == "undefined") plDataBlock = '';
    let configs = CONFIG.get("menu");
    let utw = mc.newCustomForm();
    utw.setTitle("§l§e请输入需要填充的(§4方块ID§e)");
    utw.addInput("方块ID", "只能是方块ID", plDataBlock);
    player.sendForm(utw, (player, datas) => {
        if (datas == null) {
            CplData(player);
            msg(player, "已取消操作!!", 4);
            return false;
        }
        let SonData = configs[plData.type].list[id];
        if (typeof SonData.fill != "undefined") {
            /* 插件填充 */
            msg(player, "正在处理中!", 3);
            if (!/:/.test(datas[0])) {
                datas[0] = "minecraft:" + datas[0];
            }
            yofill(plData.pos.data[0], plData.pos.data[1], datas[0], player.pos.dimid);
            msg(player, "处理完成!", 2);
        } else {
            /* 直接执行 */
            let cmd = SonData.cmd;

            let seCount = cmd.match(/{pos\[\d+\]}/g);
            if (seCount == null) {
                cmd = cmd.replace(/{pos\[\d+\]}/g, '');
            } else {

                seCount.forEach((v, k) => {
                    if (plData.pos.data[k] instanceof Object) {
                        cmd = cmd.replace(v, postostr(plData.pos.data[k]));
                    } else {
                        cmd = cmd.replace(v, '');
                    }
                });
            }
            cmd = cmd.replace(/{block}/g, datas[0]);
            player.runcmd(cmd);
        }

        player.setExtraData(Cname + "_block", datas[0]);
        CplData(player);
    });

}


function postostr({ x, y, z }) {
    return `${x} ${y} ${z}`
}

function yofill(pos1, pos2, block, dimid = 0) {
    let pos1_x = pos1.x > pos2.x ? pos2.x : pos1.x, pos1_y = pos1.y > pos2.y ? pos2.y : pos1.y, pos1_z = pos1.z > pos2.z ? pos2.z : pos1.z;
    let pos2_x = pos1.x < pos2.x ? pos2.x : pos1.x, pos2_y = pos1.y < pos2.y ? pos2.y : pos1.y, pos2_z = pos1.z < pos2.z ? pos2.z : pos1.z;

    for (pos1_y; pos1_y <= pos2_y; pos1_y++) {
        pos1_z = pos1.z > pos2.z ? pos2.z : pos1.z;
        pos2_z = pos1.z < pos2.z ? pos2.z : pos1.z;
        for (pos1_z; pos1_z <= pos2_z; pos1_z++) {
            pos1_x = pos1.x > pos2.x ? pos2.x : pos1.x;
            pos2_x = pos1.x < pos2.x ? pos2.x : pos1.x;
            for (pos1_x; pos1_x <= pos2_x; pos1_x++) {
                mc.setBlock(pos1_x, pos1_y, pos1_z, dimid, block);
            }
        }
    }

}

function onServerStarted() {
    colorLog("green", "[快捷创造] 加载完成了哦! v0.0.3 作者:Yoyo");
}